/*
Copyright (c) 2009, Luke Berndt
All rights reserved.
 
 * More Information: http://www.tagflo.com

Redistribution and use in source and binary forms, with or without modification, are permitted 
provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions 
  and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this list of conditions 
  and the following disclaimer in the documentation and/or other materials provided with the distribution.

* Neither the name of RoboTastic Software nor the names of its contributors may be used to endorse or 
  promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
POSSIBILITY OF SUCH DAMAGE.
*/


using System;
using System.Windows;
using System.Windows.Input;
using System.Diagnostics;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Text;
using System.IO;
using System.Data.SqlServerCe;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.Linq;
using System.Data;
using System.Threading;

namespace TagFlo
{
    class ImportWorkItem
    {
        public enum ImportAction { None, Scan, AddDirectory, RemoveDirectory, AddFile, RemoveFile };
        ImportAction action;
        string _path;


        public ImportWorkItem(string path, ImportAction a)
        {
            action = a;
            _path = path;
        }

        public ImportWorkItem(ImportAction a)
        {
            action = a;
            _path = null;
        }
        public ImportAction Action
        {
            get
            {
                return action;
            }
        }

        public string Path
        {
            get
            {
                return _path;
            }
        }
    }



    public class ImportWorker
    {
        PhotoDBEntities photoEntities;
        ThreadedObservableCollection<Photo> photoCollection;
       ThreadedObservableCollection<Path> pathCollection;
       ThreadedObservableCollection<Tag> tagCollection;

        DateTime start;
        int fileCount;
        
        enum ScanAction { none, update, add };


        Queue<ImportWorkItem> work;
        MainWindow parent;
        private delegate void NoArgDelegate();


        public static readonly RoutedEvent DirectoryChangeEvent =
          EventManager.RegisterRoutedEvent("ImportDirectoryChange",
                                          RoutingStrategy.Bubble,
                                          typeof(RoutedEventHandler),
                                          typeof(ImportWorker));

        public static readonly RoutedEvent FileChangeEvent =
          EventManager.RegisterRoutedEvent("ImportFileChange",
                                          RoutingStrategy.Bubble,
                                          typeof(RoutedEventHandler),
                                          typeof(ImportWorker));

        public event EventHandler FileChanged;
        public event EventHandler DirectoryChanged;


        protected virtual void OnFileChanged(EventArgs e)
        {
            if (FileChanged != null)
                FileChanged(this, e);
        }

        protected virtual void OnDirectoryChanged(EventArgs e)
        {
            if (DirectoryChanged != null)
                DirectoryChanged(this, e);
        }



        public ImportWorker(MainWindow mWindow)
        {
            parent = mWindow;

            photoCollection = mWindow.photoCollection;
            tagCollection = mWindow.tagCollection;
            pathCollection = mWindow.pathCollection;
            
            photoEntities = mWindow.photoEntities;
            
            work = new Queue<ImportWorkItem>();
        }


        private void ImportFile(FileInfo f)
        {
            
                //string sqlFilePath = f.FullName.Replace(@"'", @"''");
            
                //Photo photo = context.Photos.FirstOrDefault(p => p.FullFilename == f.FullName);
            //Photo photo = photoEntities.Photos.FirstOrDefault(p => p.FullFilename == f.FullName);

            Photo photo = photoEntities.Photos.Where("it.FullFilename = '"+f.FullName + "'").FirstOrDefault();

                ScanAction scanFile = ScanAction.none;

                // SQL strings can not have standalone ', you need to have ''

                // Use the Select method to find all rows matching the filter.


                // The file is not in the DB, Add it
                if (photo == null)
                {
                    photo = Photo.New(); // new Photo();
                    scanFile = ScanAction.add; // The file is not in the DB, add it.
                }
                else
                {
                    // The file is in the DB, check to see if it needs to be updated

                    DateTime dbDate;
                    DateTime fileDate;


                    // Get the dates from the file and DB
                    dbDate = DateTime.Parse(photo.DateModified.ToString());
                    fileDate = new DateTime(f.LastWriteTime.Year, f.LastWriteTime.Month, f.LastWriteTime.Day, f.LastWriteTime.Hour, f.LastWriteTime.Minute, f.LastWriteTime.Second);

                    int dateCompare = DateTime.Compare(fileDate, dbDate);

                    // If the File is more current, update the DB
                    if (dateCompare != 0)
                    {
                        scanFile = ScanAction.update;
                    }
                }

                // If the file needs to be Updated or Added
                if (scanFile != ScanAction.none)
                {

                    PhotoFile p = new PhotoFile(f.FullName);







                    // Send out a status message
                    if (scanFile == ScanAction.add)
                    {
                        Trace.WriteLine("Adding file: " + f.FullName);
                    }
                    else
                    {
                        Trace.WriteLine("Updating file: " + f.FullName);
                    }


                    DateTime dt;

                    // Initial values in case some of the MetaData can not be read

                    photo.Rating = (short)p.Metadata.Rating;
                    photo.HorizontalResolution = -1;
                    photo.VerticalResolution = -1;
                    photo.ExposureTime = -1;
                    photo.ExposureCompensation = -1;
                    photo.LensAperture = -1;
                    photo.FocalLength = -1;
                    photo.IsoSpeed = -1;
                    photo.FlashFired = false;
                    photo.ExposureMode = -1;
                    photo.WhiteBalanceMode = -1;
                  

                    try
                    {

                        if (DateTime.TryParse(p.Metadata.DateTaken, out dt))
                        {
                            photo.DateTaken = dt;
                        }
                        else
                        {
                            dt = f.CreationTime;
                            photo.DateTaken = f.CreationTime;
                        }


                        photo.Width = (int)p.width;
                        photo.Height = (int)p.height;
                        /*row["Year"] = dt.ToString("yyyy");
                        row["Month"] = dt.ToString("MMMM");
                        row["Day"] = dt.ToString("%d");
                        row["Date"] = dt.ToString("MMMM") + " " + dt.ToString("dd") + ", " + dt.ToString("yyyy");*/
                        photo.Filename = f.Name;                   // When working with a row, we do not need to replace single (')
                        //. = f.Directory.FullName;    // When working with a row, we do not need to replace single (')
                        photo.FullFilename = f.FullName;                   // When working with a row, we do not need to replace single (')
                        photo.Thumbnail = p.ThumbnailByteArray();
                        photo.DateModified = f.LastWriteTime;


                       /* Path path = (from pathTable in photoEntities.Paths
                     where pathTable.FullPath == f.Directory.FullName.ToString()
                                     select pathTable).FirstOrDefault();
                        */

                        Path path = photoEntities.Paths.Where("it.FullPath ='"+  f.Directory.FullName.ToString() + "'").FirstOrDefault();


                        if (path != null)
                        {
                            
                            photo.Paths = path;
                        }
                        else
                        {
                           string  parentPathString = f.Directory.Parent.FullName;
                          /* Path parentPath = (from pathTable in photoEntities.Paths
                     where pathTable.FullPath == parentPathString select pathTable).FirstOrDefault();*/

                           Path parentPath = photoEntities.Paths.Where("it.FullPath = '" + parentPathString + "'").FirstOrDefault();


                           path = Path.New();//new Path();

                            
                            path.FullPath = f.Directory.FullName.ToString();
                            if (parentPath == null)
                            {
                                path.Parent = null;
                                //path.ParentPathID = 0;
                                path.IsRoot = 1;
                            }
                            else
                            {
                                path.Parent = parentPath;
                                path.IsRoot = 0;
                            }
                            pathCollection.Add(path);
                            photoEntities.AddToPaths(path);
                            //context.AddToPaths(path);
                            photo.Paths = path;
                            //photo.PathID = path.PathID;

                        }

                    }
                    catch (Exception ex)
                    {
                        Trace.WriteLine("Error adding Image File related metadata: " + ex.Message);
                    }

                    try
                    {
                        photo.Title = p.Metadata.Title;
                        photo.Comment = p.Metadata.Comment;
                        photo.Rating = (short)p.Metadata.Rating;
                        photo.Subject = p.Metadata.Subject;
                        photo.CameraManufacturer = p.Metadata.CameraManufacturer;
                        photo.CameraModel = p.Metadata.CameraModel;
                        photo.HorizontalResolution = (int)p.Metadata.HorizontalResolution;
                        photo.VerticalResolution = (int)p.Metadata.VerticalResolution;
                        photo.ExposureTime = (int)p.Metadata.ExposureTime;
                        photo.ExposureCompensation = (int)p.Metadata.ExposureCompensation;
                        photo.LensAperture = (int)p.Metadata.LensAperture;
                        photo.FocalLength = (int)p.Metadata.FocalLength;
                        photo.IsoSpeed = (int)p.Metadata.IsoSpeed;
                        if (p.Metadata.FlashMode != 0) { photo.FlashFired = true; } else { photo.FlashFired = false; };
                        photo.ExposureMode = p.Metadata.ExposureMode;
                        photo.WhiteBalanceMode = p.Metadata.WhiteBalanceMode;
                    }
                    catch (Exception ex)
                    {
                        Trace.WriteLine("Error adding Camera Related metadata: " + ex.Message);
                    }




                    //photoTable.ThreadedAddRow(row); // add the new row
                    // Tag Table
                    try
                    {
                        
                        if (p.Metadata.TagList != null)
                        {
                            foreach (string tag in p.Metadata.TagList)
                            {
                               
                                //Tag t =  photoEntities.Tags.FirstOrDefault(i => i.TagName == tag);
                                Tag t = photoEntities.Tags.Where("it.TagName = '" +  tag + "'").FirstOrDefault();
                                
                                if (t == null)
                                {
                                    t = Tag.New();// new Tag();
                                    t.TagName = tag;
                                    t.TagType = 0;
                                    t.ParentTagID = 0;

                                    photoEntities.AddToTags(t);
                                    tagCollection.Add(t);
                                    
                                }
                                photo.Tags.Add(t);
                               // context.PhotoTag_Mappings.InsertOnSubmit(photo.CreateTagMap(t));
                               
                               
                                
                            }
                        }
                    }

                    catch (Exception ex)
                    {
                        Trace.WriteLine("Trouble adding tags for file: " + f.FullName + " Error: " + ex.Message);
                    }






                    parent.AddFileUpdate("+ " + f.Name, p.ThumbnailByteArray());
                    //context.AddToPhotos(photo);
                    photoCollection.Add(photo);
                    photoEntities.AddToPhotos(photo);
                    //context.Photos.InsertOnSubmit(photo);
                    OnFileChanged(EventArgs.Empty);
                }
                else
                {
                    // This is where you would need to handle updated files
                    Trace.WriteLine(f.FullName + " is already in DB.");
                }
                //context.SubmitChanges();
                //context.SaveChanges();
                photoEntities.SaveChanges();
            
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="path">The string path describes where the program should scan for new files and directories.
        /// Since path is used to create DirectoryInfo objects, it may have single (') which need to be doubled for SQL</param>
        private void AddDirectoryHandler(string path)
        {

            DirectoryInfo _directory = new DirectoryInfo(path);

            string st = _directory.LastWriteTime.ToString();
            //string sqlDirPath = _directory.FullName.Replace(@"'", @"''"); // need to replace any single ' for SQL
            /*Path dbPath = (from pathTable in photoEntities.Paths
                           where pathTable.FullPath == _directory.FullName
                           select pathTable).FirstOrDefault();*/

            Path dbPath = photoEntities.Paths.Where("it.FullPath = '"+ _directory.FullName + "'").FirstOrDefault();

            if (dbPath == null)
            {
                //eck!
            }
            
            
            Trace.WriteLine("Starting " + path + " Scan: " + DateTime.Now.TimeOfDay);

            try
            {
                // Check to see if there are any SubDirectories which have not been imported
                foreach (DirectoryInfo d in _directory.GetDirectories())
                {
                    // Use the Select method to find all rows matching the filter.

                    //In order to make the path string sql safe, we need to double any (')s
                   // string sqlFilePath = d.FullName.Replace(@"'", @"''");
                    /*Path subDirPath = (from pathTable in photoEntities.Paths
                                   where pathTable.FullPath == d.FullName
                                   select pathTable).FirstOrDefault();*/
                    Path subDirPath = photoEntities.Paths.Where("it.FullPath = '" + d.FullName + "'").FirstOrDefault();


                    if (subDirPath == null)
                    {
                        AddDirectory(d.FullName);
                    }
                }


                // Go through all the files in the directory, new or modified files will be updated

                foreach (FileInfo f in _directory.GetFiles("*.jpg"))
                {
                    try
                    {

                        ImportFile(f);
                    }
                    catch (Exception ex)
                    {
                        Trace.WriteLine("Error adding file: " + f.ToString() + " - " + ex.Message);
                    }
                    //Thread.Sleep(10);
                }

                /// Go through all the files in PhotoTable that are supposed to be in this 
                /// diectory to check and see if they are still here

                // Remove any files  from the Photo Table
                //lock (photoTable.Rows.SyncRoot)
                //{
                    foreach (Photo p in dbPath.Photos)
                    {
                        FileInfo fileInfo = new FileInfo(p.FullFilename);
                        if (fileInfo.Exists == false)
                        {
                            RemoveFile(fileInfo.FullName);
                        }
                    }

                //}

                // Update the import table so LastChecked and DateModified are accurate.
                //lock (importTable.Rows.SyncRoot)
                //{

                    //foundRows = importTable.Select("Path='" + sqlDirPath + "'");

                   // if (foundRows.Length == 1)
                   // {
                        //foundRows[0]["LastChecked"] = DateTime.Now.ToString();
                        //foundRows[0]["DateModified"] = _directory.LastWriteTime.ToString();
                        dbPath.LastChecked = DateTime.Now;
                        dbPath.DateModified = _directory.LastWriteTime;
                   // }
                   // else
                   // {
                   //     Trace.WriteLine("Error saving import table");
                   // }
                //}


                // Update the database tables

           /*     lock (photoTable.Rows.SyncRoot)
                {
                    parent.sqlDataSet.UpdatePhotoTable();
                }

                lock (importTable.Rows.SyncRoot)
                {
                    parent.sqlDataSet.UpdateImportTable();
                }

                lock (tagTable.Rows.SyncRoot)
                {
                    parent.sqlDataSet.UpdateTagTable();
                }*/
                        //context.SubmitChanges();

                        OnDirectoryChanged(EventArgs.Empty);
                        photoEntities.SaveChanges();
            }

            catch (Exception ex)
            {
                Trace.WriteLine("Error adding files: " + ex.Message);
            }
            Trace.WriteLine("Ending " + path + " Scan: " + DateTime.Now.TimeOfDay);

        }



        /// <summary>
        /// This will remove a directory, and all of its subdirectories and the files in them from the Photo, Tag and Import tables
        /// </summary>
        /// <param name="removeDir">The directory to remove.</param>
        public void RemoveDirectoryHandler(string removeDir)
        {
            //In order to make the path string sql safe, we need to double any (')s
            //string sqlRemoveDir = removeDir.Replace(@"'", @"''");
            /*
            var paths = from pathTable in photoEntities.Paths.Include("Photos")
                           where pathTable.FullPath.St
                           select pathTable;
            */
            var paths = photoEntities.Paths.Include("Photos").Where("it.FullPath = '" + removeDir+ "'");

            int c = paths.Count();
            // Remove any files in the Dir or Sub-Dir from the Photo Table
           // lock (photoTable.Rows.SyncRoot)
            //{
               // importViewPhotoTable.RowFilter = "Path LIKE '" + sqlRemoveDir + "%'";
                foreach (Path path in paths.ToList())
                {
                 /*   for (int i = 0; i < path.Photos.Count(); i++)
                    {
                        Photo photo = path.Photos.ToArray()[i];
                        photo.Tags.Clear();
                        photo.PhotoSets.Clear();
                        photoEntities.DeleteObject(photo);
                       


                    }*/
                    foreach (Photo photo in path.Photos.ToList())
                    {
                        photo.Tags.Clear();
                        photo.PhotoSets.Clear();
                        photoEntities.DeleteObject(photo);
                        photoCollection.Remove(photo);
                        //path.Photos.Remove(photo);

                    }

                    foreach (Path childPath in path.Paths.ToList())
                    {
                        RemoveDirectory(childPath.FullPath);
               
                    }

                    pathCollection.Remove(path);
                    photoEntities.DeleteObject(path);
                    
                    //row.Delete();
                }

                OnDirectoryChanged(EventArgs.Empty);
                photoEntities.SaveChanges();

                //importViewPhotoTable.RowFilter = null;
                //parent.sqlDataSet.UpdatePhotoTable();
            //}


            // Remove any files in the Dir or Sub-Dir from the PhotoSet Table
            /*lock (photoSetTable.Rows.SyncRoot)
            {
                importViewPhotoSetTable.RowFilter = "Path LIKE '" + sqlRemoveDir + "%'";
                foreach (DataRowView row in importViewPhotoSetTable)
                {
                    if (row.RowVersion == DataRowVersion.Current)
                    {
                        row.Delete();
                    }
                }
                importViewPhotoSetTable.RowFilter = null;
                parent.sqlDataSet.UpdatePhotoSetTable();
            }*/


            // Remove the Dir from the import table
            /*lock (importTable.Rows.SyncRoot)
            {
                importViewImportTable.RowFilter = "Path LIKE '" + sqlRemoveDir + "%'";
                foreach (DataRowView row in importViewImportTable)
                {
                    row.Delete();

                }
                importViewImportTable.RowFilter = null;
                parent.sqlDataSet.UpdateImportTable();
            }
            */

            // Remove any files in the Dir or Sub-Dir from the Tag Table
           /* lock (tagTable.Rows.SyncRoot)
            {
                importViewTagTable.RowFilter = "Path LIKE '" + sqlRemoveDir + "%'";
                foreach (DataRowView row in importViewTagTable)
                {
                    row.Delete();

                }
                importViewTagTable.RowFilter = null;
                parent.sqlDataSet.UpdateTagTable();
            }
            */

        }

        /// <summary>
        /// This will remove a file from the Photo, PhotoSet, Tag and Import tables
        /// </summary>
        /// <param name="removeDir">The File to remove.</param>
        public void RemoveFileHandler(string removeFile)
        {
            //In order to make the path string sql safe, we need to double any (')s
           // string sqlRemoveFile = removeFile.Replace(@"'", @"''");

            /*Photo photo = (from photoTable in photoEntities.Photos
                        where photoTable.FullFilename == removeFile
                        select photoTable).FirstOrDefault();*/

            Photo photo = photoEntities.Photos.Where("it.FullFilename = '" + removeFile +"'").FirstOrDefault();

            Trace.WriteLine("Removing File From DB: " + removeFile);

            photo.Tags.Clear();
            photo.PhotoSets.Clear();

            photoEntities.DeleteObject(photo);
            photoEntities.SaveChanges();
            OnFileChanged(EventArgs.Empty);

            // Remove any files  from the Photo Table
           /* lock (photoTable.Rows.SyncRoot)
            {
                importViewPhotoTable.RowFilter = "Path LIKE '" + sqlRemoveFile + "'";
                foreach (DataRowView row in importViewPhotoTable)
                {
                    row.Delete();
                }
                importViewPhotoTable.RowFilter = null;
                parent.sqlDataSet.UpdatePhotoTable();
            }


            // Remove any files from the PhotoSet Table
            lock (photoSetTable.Rows.SyncRoot)
            {
                importViewPhotoSetTable.RowFilter = "Path LIKE '" + sqlRemoveFile + "'";
                foreach (DataRowView row in importViewPhotoSetTable)
                {
                    if (row.RowVersion == DataRowVersion.Current)
                    {
                        row.Delete();
                    }
                }
                importViewPhotoSetTable.RowFilter = null;
                parent.sqlDataSet.UpdatePhotoSetTable();
            }

            // Remove any files from the Tag Table
            lock (tagTable.Rows.SyncRoot)
            {
                importViewTagTable.RowFilter = "Path LIKE '" + sqlRemoveFile + "'";
                foreach (DataRowView row in importViewTagTable)
                {
                    row.Delete();

                }
                importViewTagTable.RowFilter = null;
                parent.sqlDataSet.UpdateTagTable();
            }
            */

        }



        public void ScanDirectories()
        {
            DirectoryInfo dir;
            DateTime dbDate;
            DateTime fileDate;

            Trace.WriteLine("Starting scan: " + DateTime.Now.TimeOfDay);


            


            //foreach (DataRow row in importTable.Rows) //(DataRow row in importDataTable.Rows)
           
            foreach (Path path in photoEntities.Paths)
            {
                //lock (importTable.Rows.SyncRoot)
               // {

                    try
                    {
                        //string dirString = path.FullPath.Replace(@"''", @"'");//row["Path"].ToString().Replace(@"''", @"'");
                        dir = new DirectoryInfo(path.FullPath);


                        if (dir.Exists == true)
                        {
                            if (path.DateModified== null) //if (row["DateModified"].ToString() == "") // we needto make sure that the directory has been checked and has a DateModified value
                            {

                                Trace.WriteLine(path.FullPath + " Has not been examined yet!");
                                AddDirectory(dir.FullName);
                            }
                            else
                            {

                                //In order to make the path string sql safe, we need to double any (')s

                                dbDate = (DateTime) path.DateModified; //DateTime.Parse(row["DateModified"].ToString());
                                fileDate = new DateTime(dir.LastWriteTime.Year, dir.LastWriteTime.Month, dir.LastWriteTime.Day, dir.LastWriteTime.Hour, dir.LastWriteTime.Minute, dir.LastWriteTime.Second);

                                int dateCompare = DateTime.Compare(fileDate, dbDate);
                                if (dateCompare != 0)
                                {
                                    //if ((Boolean)row["Exclude"] == false)
                                    {
                                        Trace.WriteLine("Something new in: " + path.FullPath);
                                        AddDirectory(dir.FullName);
                                    }
                                }
                                else
                                {
                                    Trace.WriteLine("Nothing new in: " + path.FullPath);
                                }
                            }
                        }
                        else
                        {
                            // the directory we are scanning no longer exists

                            Trace.WriteLine("Removing Directory From DB: " + path.FullPath);

                            RemoveDirectory(dir.FullName);
                        }
                    }
                    catch (Exception ex)
                    {
                        Trace.WriteLine("Exception Scanning directory: " + path.FullPath + " Error: " + ex.Message);
                    }
                   // row.BeginEdit();
                   // row["LastChecked"] = DateTime.Now.ToString();
                   // row.EndEdit();
                    path.LastChecked = DateTime.Now;

                //}
            }
            photoEntities.SaveChanges();
            //context.SubmitChanges();
           /* lock (importTable.Rows.SyncRoot)
            {
                parent.sqlDataSet.UpdateImportTable();
            }*/

            Trace.WriteLine("Ending scan: " + DateTime.Now.TimeOfDay);

        }

        public void DoWork()
        {
            ImportWorkItem workItem;

            while (true)
            {
                if (work.Count > 0)
                {
                    while (work.Count > 0)
                    {
                        lock (work)
                        {
                            workItem = work.Dequeue();
                        }
                        switch (workItem.Action)
                        {
                            case ImportWorkItem.ImportAction.Scan:
                                start = DateTime.Now;
                                fileCount = 0;
                                ScanDirectories();
                                Trace.WriteLine("Scanning took: " + DateTime.Now.Subtract(start).ToString() + " To Process " + fileCount + " Files");

                                break;
                            case ImportWorkItem.ImportAction.AddDirectory:
                                AddDirectoryHandler(workItem.Path);
                                break;
                            case ImportWorkItem.ImportAction.RemoveDirectory:
                                RemoveDirectoryHandler(workItem.Path);
                                break;
                            case ImportWorkItem.ImportAction.RemoveFile:
                                RemoveFileHandler(workItem.Path);
                                break;

                        }
                    }


                    NoArgDelegate selectTreeUpdater = new NoArgDelegate(parent.UpdateSelectTree);
                    parent.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Send, selectTreeUpdater);
                }
                Thread.Sleep(100);
            }
        }

        public void AddScan()
        {
            ImportWorkItem tempWork = new ImportWorkItem(ImportWorkItem.ImportAction.Scan);

            lock (work)
            {
                work.Enqueue(tempWork);
            }
        }

        public void RemoveDirectory(string path)
        {
            ImportWorkItem tempWork = new ImportWorkItem(path, ImportWorkItem.ImportAction.RemoveDirectory);

            lock (work)
            {
                work.Enqueue(tempWork);
            }
        }

        public void RemoveFile(string path)
        {
            ImportWorkItem tempWork = new ImportWorkItem(path, ImportWorkItem.ImportAction.RemoveFile);

            lock (work)
            {
                work.Enqueue(tempWork);
            }
        }


        public void AddDirectory(string dirPath)
        {
            //string sqlPath = dirPath.Replace(@"'", @"''"); // we need to do this because SQL can not handle single 's


           /* Path path = (from pathTable in photoEntities.Paths
                         where pathTable.FullPath == dirPath
                         select pathTable).FirstOrDefault();*/
            Path path = (from pathTable in photoEntities.Paths.Where("it.FullPath = '" + dirPath+"'") select pathTable).FirstOrDefault();
           


            if (path == null)
            {
                DirectoryInfo d = new DirectoryInfo(dirPath);

               string parentPathString = d.Parent.FullName;
                /*Path parentPath = (from pathTable in photoEntities.Paths
                                   where pathTable.FullPath == parentPathString
                                   select pathTable).FirstOrDefault();*/
               Path parentPath = photoEntities.Paths.Where("it.FullPath='" + parentPathString + "'").FirstOrDefault();
               path = Path.New(); // new Path();


                path.FullPath = d.FullName;
                if (parentPath == null)
                {
                    path.Parent = null;
                    //path.ParentPathID = 0;
                    path.IsRoot = 1;
                }
                else
                {
                    path.IsRoot = 0;
                   // path.ParentPathID = parentPath.PathID;
                    path.Parent = parentPath;
                }
                pathCollection.Add(path);
                photoEntities.AddToPaths(path);
                photoEntities.SaveChanges();
                //context.Paths.InsertOnSubmit(path);
               // context.SubmitChanges();
                //context.AddToPaths(path);
                //photo.PathID = path.PathID;

            }

            /*DataRow[] foundRows;
            
            String s = "Path='" + sqlPath + "'";
            foundRows = importTable.Select(s);

            if (foundRows.Length == 0)
            {
                lock (importTable.Rows.SyncRoot)
                {
                    DataRow row = importTable.ThreadedNewRow();
                    row["Path"] = path;        // When working with a row, we do not need to replace single (')
                    row["Exclude"] = 0;

                    importTable.ThreadedAddRow(row);

                    parent.sqlDataSet.UpdateImportTable();
                }
            }*/
            ImportWorkItem tempWork = new ImportWorkItem(dirPath, ImportWorkItem.ImportAction.AddDirectory);
            
            lock (work)
            {
                work.Enqueue(tempWork);
            }

        }

    }

}

